﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using JXT.PrimaryKey.Batman.Log;
using JXT.PrimaryKey.Batman.Cache;
using JXT.PrimaryKey.Batman.Container;
using JXT.PrimaryKey.Batman.Language;
using JXT.PrimaryKey.Batman.Core.Extensions;
using JXT.PrimaryKey.Batman.Core.Security;
using JXT.PrimaryKey.Batman.Core.Language;
using JXT.PrimaryKey.Batman.Core.Infrastructure;
//using JXT.PrimaryKey.Batman.WcfService;
using JXT.PrimaryKey.Batman.WcfService.Client;
using JXT.PrimaryKey.Batman.Web.Security;
using JXT.PrimaryKey.Batman.Web.Mvc.Models;
using JXT.PrimaryKey.Batman.Web.Mvc.Results;

namespace JXT.PrimaryKey.Batman.Web.Mvc.Controllers
{
    public abstract class BaseController : Controller
    {
        private SupernovaWebContext _context;
        public SupernovaWebContext Context
        {
            get
            {
                if (_context == null)
                {
                    _context = new SupernovaWebContext(ControllerContext.RequestContext,
                        RouteTable.Routes,
                        ContainerManager.Default.Resolve<ILanguage>());
                }
                return _context;
            }
        }

        protected TService LoadService<TService>()
        {
            return ContainerManager.Service.Resolve<TService>();
        }
        private IServiceFactory _service;

        public IServiceFactory Service
        {
            get
            {
                if (_service == null)
                {
                    //_service = new ServiceFactory(Context.Configuration.ServiceConfiguration.Url);
                    _service = ServiceFactory.Create(Context.Configuration.ServiceConfiguration.Url.ToString());
                }
                return _service;
            }
        }

        private ILogger _logger;

        public ILogger Logger
        {
            get
            {
                if (_logger == null)
                {
                    _logger = ContainerManager.Default.Resolve<ILogger>();
                }
                return _logger;
            }
        }

        private ICache _cache;

        public ICache Cache
        {
            get
            {
                if (_cache == null)
                {
                    _cache = ContainerManager.Default.Resolve<ICache>();
                }
                return _cache;
            }
        }

        private IMembership _membership;

        public IMembership Membership
        {
            get
            {
                if (_membership == null)
                {
                    _membership = new Membership(Service, Context);
                }
                return _membership;
            }
        }

        public ActionResult Message(string message)
        {
            return Message(null, message, MessageIcon.Information);
        }

        protected ActionResult Message(string title, string message, MessageIcon icon = MessageIcon.Information, params JumpUrl[] urls)
        {
            return Message(title, message, icon, false, urls);
        }

        protected ActionResult Message(string title, string message, MessageIcon icon = MessageIcon.Information, bool isAppendUrl = false, params JumpUrl[] urls)
        {
            ViewMessage viewMessage = new ViewMessage();
            if (!String.IsNullOrEmpty(title))
                viewMessage.Title = title;
            if (!String.IsNullOrEmpty(message))
                viewMessage.Message = message;
            viewMessage.Icon = icon;
            if (urls != null && urls.Length > 0)
            {
                if (isAppendUrl)
                {
                    viewMessage.Urls.AddRange(urls);
                }
                else
                {
                    viewMessage.Urls = new List<JumpUrl>(urls);
                }
            }
            return Message(viewMessage);
        }

        protected ActionResult Message(ViewMessage message)
        {
            return new MessageResult()
            {
                Message = message
            };
        }

        private static readonly string _verifyCodeCookieKey = "supernova_verifycode";
        protected void WriteVerifyCode(string code)
        {
            string securityCode = AesHelper.Encode(code.ToLower().ToMd5(), Context.Configuration.VerifyCodeKey);
            Response.Cookies.Add(new System.Web.HttpCookie(_verifyCodeCookieKey, securityCode));
        }

        protected bool IsValidVerifyCode(string code, bool isAddModelError = false, string errorMessage = "")
        {
            var cookie = Request.Cookies[_verifyCodeCookieKey];
            if (cookie == null || code == null)
            {
                if (isAddModelError)
                    addVerifyCodeError(errorMessage);
                return false;
            }
            string securityCode = AesHelper.Encode(code.ToLower().ToMd5(), Context.Configuration.VerifyCodeKey);
            var result = securityCode == cookie.Value;
            if (isAddModelError && !result)
            {
                addVerifyCodeError(errorMessage);
            }
            return result;
        }

        private void addVerifyCodeError(string errorMessage)
        {
            if (String.IsNullOrEmpty(errorMessage))
                errorMessage = Context.String("SystemWeb_CommonString_VerifyCodeError");
            ModelState.AddModelError("VerifyCode", errorMessage);
        }
        [NonAction]
        public ActionResult Jsonp(string callback, object data)
        {
            return new JsonpResult(callback)
            {
                Data = data
            };
        }
        protected override void OnException(ExceptionContext filterContext)
        {
            base.OnException(filterContext);
            if (filterContext.Exception != null)
            {
                try
                {
                    Logger.Error("system has a exception", filterContext.Exception);
                }
#if DEBUG
                catch (Exception e)
                {
                    System.Diagnostics.Debug.Fail("Logging error fail,full message is:" + e.Message);
                }
#else
                catch
                {
                }
#endif
#if DEBUG
#else
                var view = new ViewResult() { ViewName = "error" };
                view.ViewBag.Title = "system has a exception!";
                view.ViewBag.Exception = filterContext.Exception;
                filterContext.Result = view;
                filterContext.ExceptionHandled = true;
#endif
            }
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (_service != null)
                _service.Dispose();
        }
    }
}
